package yartiss.engine.simulation.events;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import yartiss.engine.simulation.Event;
import yartiss.engine.simulation.system.ITask;

public class EventGenerator {
	
	private List<IEventGeneratedListener> listeners = new ArrayList<IEventGeneratedListener>();
	private static List<String> availableStrings;
	
	static {// ATTENTION : doit renvoyer la meme chose que event.toString() // design pourri de younes :)
		availableStrings = new ArrayList<String>();
		availableStrings.add("activate_task" );
		availableStrings.add("job_execution_end");
		availableStrings.add("job_execution_begin");
		availableStrings.add("check_completion");
		availableStrings.add("check_deadline");
		availableStrings.add("deadline_missed");
		availableStrings.add("check_energy_state" );
		availableStrings.add("check_effective_deadline" );
		availableStrings.add("energy_failure" );
	}
	
	public void addEventGeneratedListener(IEventGeneratedListener l){
			listeners.add(l);
	}
	
	public void removeEventGeneratedListener(IEventGeneratedListener l){
		
		if(listeners.contains(l)){
			listeners.remove(l);
		}
	}
	
	protected void fireEventGenerated(Event event){
		for (IEventGeneratedListener l : listeners) {
			l.actionPerformed(event);
		}
	}
	
	public Event getNewInstance(String eventType, ITask task,int procId, long date, Map<String , Long> metrics){
		
		eventType = eventType.toLowerCase();
		
		if("activate_task".equals(eventType))
			return new ActivateTaskEvent(task,procId, date, metrics, this);
		if("check_deadline".equals(eventType)) 
			return new CheckDeadlineEvent(task,procId, date, metrics,this);
		if("check_effective_deadline".equals(eventType)) 
			return new CheckEffectiveDeadlineEvent(task,procId, date, metrics,this);
		if("check_energy_state".equals(eventType))
			return new CheckEnergyStateEvent(task,procId, date, metrics,this);
		if("deadline_missed".equals(eventType)) 
			return new DeadlineMissedEvent(task,procId, date, metrics,this);
		if("job_execution_end".equals(eventType)) 
			return new JobExecutionEndEvent(task,procId, date, metrics,this);
		if("job_execution_begin".equals(eventType)) 
			return new JobExecutionBeginEvent(task,procId, date, metrics,this);
		if("check_completion".equals(eventType)) 
			return new CheckCompletionEvent(task,procId, date, metrics,this);
		if("energy_failure".equals(eventType)) 
			return new EnergyFailureEvent(task,procId, date, metrics,this);
		else 
			throw new IllegalArgumentException(eventType);
	}
	
	public Event getNewInstance(String eventType, ITask task, long date, Map<String , Long> metrics){
		return getNewInstance(eventType, task,-1, date,  metrics);
	}
	
	public Event generateEvent(String eventType,int procId, ITask task, long date, Map<String, Long > metrics){
		//System.out.println("\tgenerateEvent: ["+eventType+"]"+task.toString());

		Event event = getNewInstance(eventType, task,procId, date, metrics);
		fireEventGenerated(event);
		return event;
	}
	
	public Event generateEvent(String eventType,ITask task, long date, Map<String, Long > metrics){
		return generateEvent(eventType,-1,task, date,  metrics);
	}
	
	public static List<String> getAvailableEvents(){
		return availableStrings;
	}
}
